/*
 * Graph.h
 *
 *  Created on: 11-dec.-2013
 *      Author: Axel
 */

#ifndef GRAPH_H_
#define GRAPH_H_

#include "SimInfList.h"

//make the graph class

template <class T>
class Graph {
public:
	Graph();
	~Graph();

	void addNode(Node<T>* node);
	void deleteNode(Node<T>* node);

	void addConnection(Node<T>* node, Node<T>* add, int weight);
	void deleteConnection(Node<T>* node, Node<T>* remove);
private:
	InfList<Node<T> >* nodes;
};

template <class T>
Graph<T>::Graph() {
	nodes = new InfList<Node<T>>(2, false);
}

template <class T>
Graph<T>::~Graph() {
	delete nodes;
}

template <class T>
void Graph<T>::addNode(Node<T>* node) {
	nodes->add(node);
}

template <class T>
void Graph<T>::deleteNode(Node<T>* node) {
	nodes->deleteItem(node);
}

template <class T>
void Graph<T>::addConnection(Node<T>* node, Node<T>* add, int weight) {
	node->connect(add, weight);
}

template <class T>
void Graph<T>::addConnection(Node<T>* node, Node<T>* add, int weight) {
	node->connect(add, weight);
}

template <class T>
void Graph<T>::deleteConnection(Node<T>* node, Node<T>* remove) {
	node->disconnect(remove);
}

//resembles a specific node from our graph
template <class T>
class Node {
public:
	Node(T data) {
		con = new InfList<connection<T> >(2, true);
		this->data = data;
	}

	~Node() {
		delete con;
	}

	//connect a new node
	void connect(Node<T>* node, int weight);
	//disconnect certain nodes
	void disconnect(Node<T>* node);

private:
	T data;
	InfList<connection<T> >* con;
};

template <class T>
void Node<T>::connect(Node<T>* node, int weight) {
	if (con->find(node)>=0) {
		connection<T> newcon;
		newcon.ptr = node;
		newcon.weight = weight;

		con->add(newcon);
	}
}

template <class T>
void Node<T>::disconnect(Node<T>* node) {
	con->deleteItem(node);
}

//resembles a single directed connection
//it contains the destination and the weight
template <class T>
struct connection {
	Node<T>* ptr;
	int weight;

	bool operator<(const connection<T>& con) const {
		return weight < con.weight;
	}

	bool operator>(const connection<T>& con) const {
		return weight > con.weight;
	}

	bool operator==(const connection<T>& con) const {
		return weight == con.weight;
	}
};


#endif /* GRAPH_H_ */
